LL1P50: PROC;
/****************************************************************
*               LL(1) GRAMMAR ANALYZER - PHASE 5		*
*PURPOSE:                                                       *
*    THIS PROGRAM ANALYZES A LL(1) GRAMMAR GIVEN IN MODIFIED    *
*    BNF FORMAT AND FINDS THE RELATION, IS-FOLLOWED-DIRECTLY-   *
*    BY, IS-DIRECT-END-OF AND IS-END-OF.			*
*INPUT:                                                         *
*    1) BASIC GRAMMAR TABLES					*
*    2) NULLABLE NON-TERMINALS AND PRODUCTIONS TABLES		*
*OUTPUT:                                                        *
*    1) FILE, $1.T03, CONTAINS THE IS-FOLLOWED-DIRECTLY-BY	*
*       RELATION.						*
*    2) FILE, $1.T04, CONTAINS THE IS-END-OF RELATION.		*
*OUTLINE:                                                       *
*REMARKS:                                                       *
****************************************************************/

/****************************************************************
* * * * * * * * * * * COMMON DATA DEFINITIONS * * * * * * * * * *
****************************************************************/

/*	* * *  COMMON REPLACEMENTS  * * *	*/
%REPLACE TRUE BY '1'B;
%REPLACE FALSE BY '0'B;

%INCLUDE 'LL1CMN.DCL';	/* GET COMMON AREAS. */


/****************************************************************
* * * * * * * * * * * COMMON PROCUDURES * * * * * * * * * * * * *
****************************************************************/


%INCLUDE 'LL1PRC.DCL';


/****************************************************************
* * * * * * * * * * GRAMMAR ANALYSIS PROCEDURES * * * * * * * * *
****************************************************************/


CALC_IFDB: PROC;
/*THIS ROUTINE IS RESPONSIBLE FOR CALCULATING THE RELATION*/
/*IS-FOLLOWED-DIRECTLY-BY.  IF SYMBOL, A, COMES BEFORE THE*/
/*SYMBOL,B, ON THE RIGTH-HAND-SIDE OF A PRODUCTION OR ALL */
/*SYMBOLS BETWEEN A AND B ARE NULLABLE. */
	DCL I BIN(15);		/* INDEXES */
	DCL J BIN(15);
	DCL K BIN(15);

/* CALCULATE THE RELATION. */
	DO I=1 TO NUMPRD;	/* LOOP THRU ALL PRODUCTIONS. */
	   IF LENGTH(RHS(I))=0 THEN /*EPSILON PRODUCTION*/
	      ;
	   ELSE
	      DO J=1 TO LENGTH(RHS(I))-1;
		 DO K=J+1 TO LENGTH(RHS(I));
		    CALL SETBIT(CHRNUM(SUBSTR(RHS(I),J,1)),
			      CHRNUM(SUBSTR(RHS(I),K,1)),ADDR(ARRAY1));
	            IF ISNLNT(SUBSTR(RHS(I),K,1)) THEN
	               ;
		    ELSE
		       K=LENGTH(RHS(I));
		 END;
	      END;
	END;

/* RETURN TO CALLER. */
	END CALC_IFDB;


CALC_IDEO: PROC;
/*THIS ROUTINE IS RESPONSIBLE FOR CALCULATING THE RELATION*/
/*IS-DIRECTLY-END-OF.  WE SAY THAT IS-DIRECTLY-END-OF IS  */
/*SIMPLY THE RIGHT TO LEFT VERSION OF THE RELATION,       */
/*BEGINS-DIRECTLY-WITH. */
	DCL I BIN(15);		/* INDEXES */
	DCL J BIN(15);

/* CALCULATE THE RELATION. */
	DO I=1 TO NUMPRD;	/* LOOP THRU ALL PRODUCTIONS. */
	   IF LENGTH(RHS(I))=0 THEN /*EPSILON PRODUCTION*/
	      ;
	   ELSE
	      DO J=LENGTH(RHS(I)) TO 1 BY -1;
		 CALL SETBIT(CHRNUM(SUBSTR(RHS(I),J,1)),
			      CHRNUM(LHS(I)),ADDR(ARRAY1));
	         IF ISNLNT(SUBSTR(RHS(I),J,1)) THEN
	            ;
		 ELSE
		    J=1;
	      END;
	END;

/* RETURN TO CALLER. */
	END CALC_IDEO;


CALC_IEO: PROC;
/*THIS ROUTINE IS RESPONSIBLE FOR CALCULATING THE RELATION*/
/*IS-END-OF.  IS-END-OF IS THE REFLEXIVE TRANSITIVE   */
/*CLOSURE OF THE RELATION, IS-DIRECTLY-END-OF. */

/* CALCULATE IT. */
	CALL CLOSUR(ADDR(ARRAY1));

/* RETURN TO CALLER. */
	END CALC_IEO;


/****************************************************************
* * * * * * * * * * * MAIN LINE PROCEDURE * * * * * * * * * * * *
****************************************************************/


/* ANALYZE THE GRAMMAR. */
	PUT SKIP LIST('BEGINNING PHASE 5 PROCESSING.');

/* CALCULATE THE RELATION, IS-FOLLOWED-DIRECTLY-BY. */
	CALL ZEROAR(ADDR(ARRAY1)); 
	PUT SKIP LIST('CALCULATING IS-FOLLOWED-DIRECTLY-BY...');
	CALL CALC_IFDB;		/*CALCULATE THE RELATION.*/
	CALL PRTARY('*** IS-FOLLOWED-DIRECTLY-BY RELATION ***',TRUE,
			 NUMVOC,NUMVOC,ADDR(ARRAY1));
	PUT SKIP LIST('SAVING THE RELATION...');
	CALL SAVARY(ADDR(ARRAY1),'T03');

/* CALCULATE THE RELATION, IS-DIRECT-END-OF. */
	CALL ZEROAR(ADDR(ARRAY1)); 
	PUT SKIP LIST('CALCULATING IS-DIRECT-END-OF...');
	CALL CALC_IDEO;		/*CALCULATE THE RELATION.*/
	CALL PRTARY('*** IS-DIRECT-END-OF RELATION ***',TRUE,
			 NUMVOC,NUMVOC,ADDR(ARRAY1));

/* CALCULATE THE RELATION, IS-END-OF. */
	PUT SKIP LIST('CALCULATING IS-END-OF...');
	CALL CALC_IEO;		/*CALCULATE THE RELATION.*/
	CALL PRTARY('*** IS-END-OF RELATION ***',TRUE, 
			 NUMVOC,NUMVOC,ADDR(ARRAY1));
	PUT SKIP LIST('SAVING THE RELATION...');
	CALL SAVARY(ADDR(ARRAY1),'T04');

/* RETURN TO CALLER. */
	PUT SKIP LIST('PHASE 5 PROCESSING COMPLETE.');
	END LL1P50;
